package com.fingard.dsp.bank.directbank.chinaums01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directbank.bankInterface.IStatement;
import com.fingard.dsp.bank.reqrespobj.statement.ReqQryStatement;
import com.fingard.dsp.bank.reqrespobj.statement.RetAtsStatement;
import com.fingard.dsp.bank.reqrespobj.statement.TransState;
import com.fingard.dsp.bank.reqrespobj.statement.detail.RetAtsStatementDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.FtpPortClient;
import com.fingard.net.FtpReceiver;
import com.fingard.net.SftpPortClient;
import com.fingard.text.SplitHelper;
import com.fingard.text.StringHelper;
import com.fingard.util.ZipHelper;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;

/**
 * 银联商务对账单
 * 
 * @author Cruise
 * @date 2018年10月11日
 */
public class ChinaUMS01Statement extends ChinaUMS01Base implements IStatement {
	@Override
	public RetAtsStatement d_Qry_Statement(ReqQryStatement p_reqQrySttm) throws Exception {
		RetAtsStatement retAts = new RetAtsStatement(p_reqQrySttm);
		retAts.writeStart();
		
		String[] posRespHeader = new String[] {"", ""};
		String posTotalNum = "0";
		
		String[] qrpayRespHeader = new String[] {"", ""};
		String qrpayTotalNum = "0";
		
		String[] tmpPosRecRespHeader = new String[] {"", ""};
		String tmpPosRecTotalNum = "0";
		
		if ("S".equals(p_reqQrySttm.statementType)) {
			posRespHeader = getPOSStatement(p_reqQrySttm, retAts);
			posTotalNum = retAts.totalNum;
			
			qrpayRespHeader = getQRPayStatement(p_reqQrySttm, retAts);
			qrpayTotalNum = retAts.totalNum;
			
			tmpPosRecRespHeader = getPosRecStatement(p_reqQrySttm, retAts);
	        tmpPosRecTotalNum = getTotalNum(retAts.totalNum);
		}
		
		if ("-1".equals(qrpayRespHeader[0]) && "-1".equals(posRespHeader[0]) && "-1".equals(tmpPosRecRespHeader[0])) {
			String respInfo = StringHelper.joinNotEmpty("\n", "POS对账单获取失败，原因:" + posRespHeader[1], "一码付对账单获取失败，原因:" + qrpayRespHeader[1] + "POS账单获取失败,原因:" + tmpPosRecRespHeader[1]);
			retAts.writeRespCode("-1");
        	retAts.writeRespInfo(respInfo);
		} else {
			if (retAts.getWrittenRdCount() == 0) {
				retAts.writeRespCode("0");
				retAts.writeRespInfo("本日无交易记录");
			} else {
				int totalNum = Integer.parseInt(posTotalNum) + Integer.parseInt(qrpayTotalNum) + Integer.parseInt(tmpPosRecTotalNum);
				retAts.isWritedTotalNum(String.valueOf(totalNum));
			}
		}
		
		retAts.writeEnd();
		return retAts;
	}

	/**
	 * POS对账单获取
	 * 
	 * 文件命名规则：商户号_yyyyMMdd_68.zip,商户号_yyyyMMdd_99.zip,
	 * @param p_reqQrySttm
	 * @param retAts
	 * @return
	 * @throws Exception
	 */
	private String[] getPOSStatement(ReqQryStatement p_reqQrySttm, RetAtsStatement retAts) throws Exception {
		String[] respHeader = new String[] { "", "" };
		
		String tmpRespCode = "";
		String tmpRespInfo = "";
		
		retAts.totalNum = "0";
		int count = 0;
		
		FtpPortClient ftpPortClient = null;

		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_reqQrySttm.actNum, "pos");
			if (actItem != null) {
				String tmpDateNow = Format.Date8Format.format(p_reqQrySttm.getBusDate());
				
				String[] tmpDownFileList = new String[] {"",""};
				tmpDownFileList[0] = actItem.merchantId + "_" + tmpDateNow + "_" + "68";
				tmpDownFileList[1] = actItem.merchantId + "_" + tmpDateNow + "_" + "99";
				
				FtpSet ftpSet = bankFront.getFtpSet("statement");
				WriteBankLogLn("FTP下载地址" + ftpSet.serverIP + ":" + ftpSet.port);
				ftpPortClient = new FtpPortClient(ftpSet);
				
				for(String tmpDownFileName : tmpDownFileList) {
					String tmpDownZipFile = tmpDownFileName + ".zip";
					String tmpFtpFilePath = StringHelper.trimEnd(ftpSet.downDir, "/") + "/" + tmpDownZipFile;
					WriteBankLogLn("当前ftp服务器待下载文件名:" + tmpFtpFilePath);
					
					String tmpLocalFilePath = createTempFileDirectory() + File.separator + tmpDownZipFile;
					WriteBankLogLn("当前ftp服务器下载文件保存本地路径:" + tmpLocalFilePath);
					
					FtpReceiver ftpReceiver = ftpPortClient.downloadFile(tmpDownFileName + ".zip", tmpLocalFilePath);
					if (ftpReceiver.isCompleted) {
					    tmpRespCode = "0";

						WriteBankLogLn("文件[" + tmpDownZipFile + "]下载已完成，开始解压...");
		            	String tmpLocalDepressDir = getTempFileDirectory();
	                    ZipHelper.unzipFile(tmpLocalFilePath, tmpLocalDepressDir, getCharset());
	                    WriteBankLogLn("文件[" + tmpDownZipFile + "]解压至已完成.");
	                    
	                    String tmpResultFilePath = getTempFileDirectory() + File.separator + tmpDownFileName + File.separator + tmpDownFileName + ".xls";
	                    WriteBankLogLn2("解压后结果文件路径:" + tmpResultFilePath);
	                    
	                    File tmpResultFile = new File(tmpResultFilePath);
	                    if (!tmpResultFile.exists()) {
	                    	respHeader[0] = "-1";
	                		respHeader[1] = "解压后结果文件:["+tmpResultFilePath+"]不存在!";
	                		return respHeader;
	                    }
	                    String tmpStrRet = readExcel(tmpResultFilePath);
	                    WriteBankLogLn2("对账单结果文件[" + tmpDownFileName + ".xls" + "]内容:\r\n" + tmpStrRet);
	                    
	                    StringReader strReader = new StringReader(tmpStrRet);
						BufferedReader tmpReader = new BufferedReader(strReader);
						
						String line1 = tmpReader.readLine();
						String[] columns = line1.split(",");
						while (true) {
							String eachline = tmpReader.readLine();
							if (eachline == null) {
								break;
							}
							String[] values = eachline.split(",");
							if (columns.length == values.length) {
								count++;
								HashMap<String, String> mapKV = SplitHelper.splitAsValueMap(columns, values);
								RetAtsStatementDetail retDetail = new RetAtsStatementDetail();
								
								if (mapKV.containsKey("银行流水号")) {
									retDetail.askNumber = mapKV.get("银行流水号").trim();
								}
								
								if (mapKV.containsKey("交易金额")) {
									retDetail.amount =Format.DecimalAmtFormat.format(Double.parseDouble(mapKV.get("交易金额").trim()));
								}
								
								if (mapKV.containsKey("交易日期") && mapKV.containsKey("交易时间")) {
									String tmpBusDate = mapKV.get("交易日期").replace("-", "").replace(":", "").replace(" ", "");
									tmpBusDate = tmpBusDate.substring(0, 8);
									String tmpBusTime = mapKV.get("交易时间").replace("-", "").replace(":", "").replace(" ", "");
									retDetail.busTime = tmpBusDate + tmpBusTime;
								}
								
								if (mapKV.containsKey("手续费")) {
									retDetail.fee = Format.DecimalAmtFormat.format(Double.parseDouble(mapKV.get("手续费").replace("`", "").trim()));
								}
								
								if (mapKV.containsKey("交易日期") && mapKV.containsKey("交易时间")) {
									String tmpBusDate = mapKV.get("交易日期").replace("-", "").replace(":", "").replace(" ", "");
									tmpBusDate = tmpBusDate.substring(0, 8);
									String tmpBusTime = mapKV.get("交易时间").replace("-", "").replace(":", "").replace(" ", "");
									retDetail.busTime = tmpBusDate + tmpBusTime;
								}
								
								if (mapKV.containsKey("终端号")) {
									retDetail.termCode = mapKV.get("终端号").trim();
								}
								
								if (mapKV.containsKey("卡号")) {
									retDetail.oppAct = mapKV.get("卡号").trim();
								}
								if (mapKV.containsKey("发卡行")) {
									retDetail.oppBank = mapKV.get("发卡行").trim();
								}
								
								retDetail.cdFlag = "22";
								retDetail.transState = TransState.Success;

								retAts.writeRetDetail(retDetail);
							} else {
								break;
							}
						}
					} else {
		            	tmpRespCode = "-1";
		            	tmpRespInfo = "当前对账单文件[" + tmpLocalFilePath + "]下载失败,原因:\r\n" + ftpReceiver.connMsg;
		            }
				}
				
				retAts.totalNum = String.valueOf(count);
			} else {
				tmpRespCode = "-1";
				tmpRespInfo = "未找到账号:[" + p_reqQrySttm.actNum + "]商户配置信息!";
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRespCode = "-1";
			tmpRespInfo = ex.getMessage();
			WriteBankLogLn(ex);
		} finally{
    		if(ftpPortClient != null){
    			try {
    				ftpPortClient.disconnect();
				} catch (IOException e) {
					e.printStackTrace();
					WriteBankLogLn(e);
				}
    		}
    	}
		
		respHeader[0] = tmpRespCode;
		respHeader[1] = tmpRespInfo;

		return respHeader;
	}
	
	/**
	 * 一码付对账单获取
	 * 
	 * 文件命名规则：商户号_yyyyMMdd_9.zip
	 * @param p_reqQrySttm
	 * @param retAts
	 * @return
	 * @throws Exception
	 */
	private String[] getQRPayStatement(ReqQryStatement p_reqQrySttm, RetAtsStatement retAts) throws Exception {
		String[] respHeader = new String[] { "", "" };
		
		String tmpRespCode = "";
		String tmpRespInfo = "";
		
		retAts.totalNum = "0";
		int count = 0;
		
		FtpPortClient ftpPortClient = null;

		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_reqQrySttm.actNum, "unifiedorder");
			if (actItem != null) {
				FtpSet ftpSet = bankFront.getFtpSet("statement");
				WriteBankLogLn("FTP下载地址" + ftpSet.serverIP + ":" + ftpSet.port);
				ftpPortClient = new FtpPortClient(ftpSet);
				
				String tmpDateNow = Format.Date8Format.format(p_reqQrySttm.getBusDate());
				String tmpDownFileName = actItem.merchantId + "_" + tmpDateNow + "_" + "9";
				String tmpDownZipFile = tmpDownFileName + ".zip";
				String tmpFtpFilePath = StringHelper.trimEnd(ftpSet.downDir, "/") + "/" + tmpDownZipFile;
				WriteBankLogLn("当前ftp服务器待下载文件名:" + tmpFtpFilePath);
				
				String tmpLocalFilePath = createTempFileDirectory() + File.separator + tmpDownZipFile;
				WriteBankLogLn("当前ftp服务器下载文件保存本地路径:" + tmpLocalFilePath);
				
				FtpReceiver ftpReceiver = ftpPortClient.downloadFile(tmpDownFileName + ".zip", tmpLocalFilePath);
				if (ftpReceiver.isCompleted) {
                    tmpRespCode = "0";

					WriteBankLogLn("文件[" + tmpDownZipFile + "]下载已完成，开始解压...");
	            	String tmpLocalDepressDir = getTempFileDirectory();
                    ZipHelper.unzipFile(tmpLocalFilePath, tmpLocalDepressDir, getCharset());
                    WriteBankLogLn("文件[" + tmpDownZipFile + "]解压至已完成.");
                    
                    String tmpResultFilePath = getTempFileDirectory() + File.separator + tmpDownFileName + File.separator + tmpDownFileName + ".xls";
                    WriteBankLogLn2("解压后结果文件路径:" + tmpResultFilePath);
                    
                    File tmpResultFile = new File(tmpResultFilePath);
                    if (!tmpResultFile.exists()) {
                    	respHeader[0] = "-1";
                		respHeader[1] = "解压后结果文件:["+tmpResultFilePath+"]不存在!";
                		return respHeader;
                    }
                    
                    String tmpStrRet = readExcel(tmpResultFilePath);
                    WriteBankLogLn2("对账单结果文件[" + tmpDownFileName + ".xls" + "]内容:\r\n" + tmpStrRet);
                    
                    StringReader strReader = new StringReader(tmpStrRet);
					BufferedReader tmpReader = new BufferedReader(strReader);
					
					String line1 = tmpReader.readLine();
					String[] columns = line1.split(",");
					while (true) {
						String eachline = tmpReader.readLine();
						if (eachline == null) {
							break;
						}
						String[] values = eachline.split(",");
						if (columns.length == values.length) {
							count++;
							HashMap<String, String> mapKV = SplitHelper.splitAsValueMap(columns, values);
							RetAtsStatementDetail retDetail = new RetAtsStatementDetail();
							
							if (mapKV.containsKey("商户订单号")) {
								retDetail.askNumber = mapKV.get("商户订单号").trim();
							}
							if (mapKV.containsKey("交易金额")) {
								retDetail.amount =Format.DecimalAmtFormat.format(Double.parseDouble(mapKV.get("交易金额").trim()));
							}
							
							if (mapKV.containsKey("交易日期") && mapKV.containsKey("交易时间")) {
								String tmpBusDate = mapKV.get("交易日期").replace("-", "").replace(":", "").replace(" ", "");
								tmpBusDate = tmpBusDate.substring(0, 8);
								String tmpBusTime = mapKV.get("交易时间").replace("-", "").replace(":", "").replace(" ", "");
								retDetail.busTime = tmpBusDate + tmpBusTime;
							}
							if (mapKV.containsKey("手续费")) {
								retDetail.fee = Format.DecimalAmtFormat.format(Double.parseDouble(mapKV.get("手续费").replace("`", "").trim()));
							}
							
							if (mapKV.containsKey("终端号")) {
								retDetail.termCode = mapKV.get("终端号").trim();
							}
							
							if (mapKV.containsKey("卡号")) {
								retDetail.oppAct = mapKV.get("卡号").trim();
							}
							if (mapKV.containsKey("发卡行")) {
								retDetail.oppBank = mapKV.get("发卡行").trim();
							}
							
							retDetail.cdFlag = "22";
							retDetail.transState = TransState.Success;

							retAts.writeRetDetail(retDetail);
						} else {
							break;
						}
					}
				} else {
	            	tmpRespCode = "-1";
	            	tmpRespInfo = "当前对账单文件[" + tmpLocalFilePath + "]下载失败,原因:\r\n" + ftpReceiver.connMsg;
	            }
				
				retAts.totalNum = String.valueOf(count);
			} else {
				tmpRespCode = "-1";
				tmpRespInfo = "未找到账号:[" + p_reqQrySttm.actNum + "]商户配置信息!";
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRespCode = "-1";
			tmpRespInfo = ex.getMessage();
			WriteBankLogLn(ex);
		} finally{
    		if(ftpPortClient != null){
    			try {
    				ftpPortClient.disconnect();
				} catch (IOException e) {
					e.printStackTrace();
					WriteBankLogLn(e);
				}
    		}
    	}
		
		respHeader[0] = tmpRespCode;
		respHeader[1] = tmpRespInfo;

		return respHeader;
	}

	 /**
     * POS对账单
     * 
     * @param p_reqQrySttm
     * @param retAts
     * @return
     * @throws Exception
     */
    private String[] getPosRecStatement(ReqQryStatement p_reqQrySttm, RetAtsStatement retAts) throws Exception {
        String[] respHeader = new String[]{"", ""};
        
        String tmpRespCode = "";
        String tmpRespInfo = "";
        
        retAts.totalNum = "0";
        int totalNum = 0;
        
        try {
        	if (StringHelper.isNullOrEmpty(p_reqQrySttm.channel)) {
        		ActSetItem actItem = getBankConfig().getActSetItem(p_reqQrySttm.actNum, "pos01");
    			if (actItem == null) {
    				respHeader[0] = "-1";
    				respHeader[1] = "未找到账号:[" + p_reqQrySttm.actNum + "]商户配置信息!";
    				return respHeader;
    			}
        	}
        	
            FtpSet ftpSet = bankFront.getFtpSet("pos");
            ftpSet.downDir = StringHelper.trimEnd(ftpSet.getDownDir("pos"), "/") + "/" + p_reqQrySttm.busDate;
            WriteBankLogLn2("银联商务POS对账单FTP服务器地址:" + ftpSet.serverIP + ":" + ftpSet.port);
            WriteBankLogLn2("银联商务POS对账单FTP服务器下载目录地址:" + ftpSet.downDir);

            StringBuilder sbFileContent = new StringBuilder();
            
            String tmpPosMode = getBankConfig().getValueAsString("posRecUseVersion");
            if ("B".equals(tmpPosMode)) {
                String downFileName = p_reqQrySttm.actNum + p_reqQrySttm.busDate + ".txt";
                WriteBankLogLn2("银联商务POS对账单所在服务器路径:" + ftpSet.downDir + "/" + downFileName);

                String localFilePath = createTempFileDirectory() + File.separator + downFileName;
                WriteBankLogLn2("银联商务POS对账单保存本地路径:" + localFilePath);

                FtpReceiver ftpReceiver = null;
                String posRecRequestType = getBankConfig().getValueAsString("posRecRequestType");
                if ("ftp".equals(posRecRequestType.toLowerCase())) {
                    FtpPortClient ftpPortClient = new FtpPortClient(ftpSet);
                    ftpReceiver = ftpPortClient.downloadFile(downFileName, localFilePath);
                } else if ("sftp".equals(posRecRequestType.toLowerCase())) {
                    SftpPortClient sftpPortClient = new SftpPortClient(ftpSet);
                    String sftpFilePath = StringHelper.trimEnd(ftpSet.downDir, "/") + "/" + downFileName;
                    WriteBankLogLn2("待下载SFTP服务器文件路径:\r\n" + sftpFilePath);
                    ftpReceiver = sftpPortClient.downloadFile("", sftpFilePath, localFilePath);
                }
                if (ftpReceiver.isCompleted) {
                    tmpRespCode = "0";

                    if (sbFileContent.length() > 0) {
                        sbFileContent.append("\n");
                    }
                    sbFileContent.append(FileHelper.readFileText(localFilePath, getCharset("UTF-8", "pos")));
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = "银联商务POS对账单下载失败,原因:\r\n" + ftpReceiver.connMsg;
                }
            } else if ("A".equals(tmpPosMode)) {
                String[] provinceArray = null;
                String provinceList = getBankConfig().getValueAsString("provinceList");
                if (provinceList.contains(",")) {
                    provinceArray = provinceList.split(",");
                }
                for (String tmpProvince : provinceArray) {
                    String downFileName = getBankConfig().getValueAsString("merchantId") + p_reqQrySttm.busDate + tmpProvince + ".txt";
                    WriteBankLogLn2("银联商务POS对账单所在服务器路径:" + ftpSet.downDir + "/" + downFileName);

                    String localFilePath = createTempFileDirectory() + File.separator + downFileName;
                    WriteBankLogLn2("银联商务POS对账单保存本地路径:" + localFilePath);

                    FtpReceiver ftpReceiver = null;
                    String posRecRequestType = getBankConfig().getValueAsString("posRecRequestType");
                    if ("ftp".equals(posRecRequestType.toLowerCase())) {
                        FtpPortClient ftpPortClient = new FtpPortClient(ftpSet);
                        ftpReceiver = ftpPortClient.downloadFile(downFileName, localFilePath);
                    } else if ("sftp".equals(posRecRequestType.toLowerCase())) {
                        SftpPortClient sftpPortClient = new SftpPortClient(ftpSet);
                        String sftpFilePath = StringHelper.trimEnd(ftpSet.downDir, "/") + "/" + downFileName;
                        WriteBankLogLn2("待下载SFTP服务器文件路径:\r\n" + sftpFilePath);
                        ftpReceiver = sftpPortClient.downloadFile("",sftpFilePath, localFilePath);
                    }
                    if (ftpReceiver.isCompleted) {
                        tmpRespCode = "0";

                        if (sbFileContent.length() > 0) {
                            sbFileContent.append("\n");
                        }
                        sbFileContent.append(FileHelper.readFileText(localFilePath, getCharset("UTF-8", "pos")));
                    } else {
                        tmpRespCode = "-1";
                        tmpRespInfo = "银联商务POS对账单下载失败,原因:\r\n" + ftpReceiver.connMsg;
                    }
                }
            } else {
            	tmpRespCode = "-1";
                tmpRespInfo = "对账单版本错误,当前版本为:[" + tmpPosMode + "].";
            }
            if (StringHelper.hasAnyChar(sbFileContent.toString())) {
            	tmpRespCode = "0";
            	
                String tmpStrRet = sbFileContent.toString();
                WriteBankLogLn2("银联商务POS对账单响应数据:\r\n" + tmpStrRet);

                StringReader strReader = new StringReader(tmpStrRet);
                BufferedReader tmpReader = new BufferedReader(strReader);

                boolean isContinue = false;
                while (true) {
                    String eachline = tmpReader.readLine();
                    if (eachline == null) {
                        break;
                    }
                    if ("".equals(eachline.trim())) {
                        continue;
                    }
                    String[] detailNodes = eachline.split("`~");
                    if (p_reqQrySttm.actNum.equals(detailNodes[1].trim())) {
                        totalNum++;
                        isContinue = true;
                        RetAtsStatementDetail tmpRetDetail = new RetAtsStatementDetail();

                        if (StringHelper.hasAnyChar(detailNodes[4])) {
                            tmpRetDetail.askNumber = detailNodes[4].trim();
                        }

                        tmpRetDetail.cdFlag = "22";

                        if (StringHelper.hasAnyChar(detailNodes[11])) {
                            tmpRetDetail.amount = StringHelper.amountDivide100(detailNodes[11].trim());
                        }

                        if (StringHelper.hasAnyChar(detailNodes[15])) {
                            tmpRetDetail.fee = StringHelper.amountDivide100(detailNodes[15].trim());
                        }

                        tmpRetDetail.busTime = detailNodes[6];

                        if (StringHelper.hasAnyChar(detailNodes[7])) {
                            tmpRetDetail.oppAct = detailNodes[7].trim();
                        }

                        if (StringHelper.hasAnyChar(detailNodes[8])) {
                            tmpRetDetail.oppActName = detailNodes[8].trim();
                        }

                        if ("2".equals(detailNodes[13].trim())) {
                            tmpRetDetail.transState = TransState.Success;
                        } else {
                            tmpRetDetail.transState = TransState.Fail;
                        }

                        retAts.writeRetDetail(tmpRetDetail);
                    }
                }

                if (!isContinue) {
                    tmpRespCode = "0";
                    tmpRespInfo = "没有符合条件的记录!";
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRespCode = "-1";
            tmpRespInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.totalNum = String.valueOf(totalNum);

        respHeader[0] = tmpRespCode;
        respHeader[1] = tmpRespInfo;

        return respHeader;
    }
}
